﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.cruxomatic.configuration.FeatureManager;
using com.cruxomatic.contracts.Plugins;
using com.cruxomatic.DTOs;
using com.cruxomatic.BusinessFacades;
using com.cruxomatic.views.Administration;
using com.cruxomatic.logging;
using com.cruxomatic.logging.Enums;
using com.cruxomatic.configuration;
using com.cruxomatic.security;
using com.cruxomatic.exceptions;

namespace com.cruxomatic.controllers.Administration
{
    public class ManageUserDetailsController
    {
        IManageUserDetails _view = null;
        public ManageUserDetailsController(IManageUserDetails view)
        {
            _view = view;
        }


        public void InitView(bool IsPostBack)
        {
            if (!IsPostBack)
            {
                CheckValidity();
                IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
                int companyid = int.Parse((new SessionData()).PageData.ToString());
                List<RoleInformation> allRoleInformation = GetRoles(companyid);
                List<DepartmentInformation> allDepartmentInformation = GetAllDepartments(companyid);
                List<CompanyInformation> allCompanies = GetAllCompanies();
                List<LocationInformation> allLocations = GetAllLocations();

                _view.AllPossibleRoles = allRoleInformation;
                _view.AllPossibleDepartments = allDepartmentInformation;
                _view.AllPossibleCompaniesToRepresent = allCompanies;
                _view.AllPossibleLocationsToRepresent = allLocations;
                if (!featureManager.IsFeatureSupported("AllowUserSystemDefinedRoleAssociation"))
                    _view.DisableRole = allRoleInformation;

                int conernedUserid = _view.ConcernedUserDetails.ConcernedUser.UserID;
                RoleFacade roleFacade = new RoleFacade();
                DepartmentFacade departmentFacade = new DepartmentFacade();
                CompanyFacade companyFacade = new CompanyFacade();
                LocationFacade locationFacade = new LocationFacade();

                UserDetailsInformation userDetails = new UserDetailsInformation();
                ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
                userDetails.Roles = cruxSecurityManager.GetRolesForUser(conernedUserid);
                userDetails.Departments = departmentFacade.GetDepartmentsForUser(conernedUserid);
                userDetails.CompaniesToRepresent = companyFacade.GetCompaniesRepresentedBy(conernedUserid);
                userDetails.LocationsToRepresent = locationFacade.GetLocationsRepresentedBy(conernedUserid);
                _view.ConcernedUserDetails = userDetails;

                ShowRepresentativePannels();
                if (featureManager.IsFeatureSupported("EditUserDetail"))
                    _view.ModificationEnabled = true;
                else
                    _view.ModificationEnabled = false;
            }
        }

        private void ShowRepresentativePannels()
        {
            bool isCompanyRepresentativeFeatureSupported = CruxConfigurationManager.SupportCompanyRepresentatives();
            bool isLocationRepresentativeFeatureSupported = CruxConfigurationManager.SupportLocationRepresentatives();
            CompanyFacade facade = new CompanyFacade();
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            int companyid = int.Parse((new SessionData()).PageData.ToString());
            bool isInternalCompany = cruxSecurityManager
                        .IsCompanyInternal(companyid);
            _view.IsCompanyRepresenativePaneVisible =
                        isCompanyRepresentativeFeatureSupported && isInternalCompany;
            _view.IsLocationRepresenativePaneVisible =
                        isLocationRepresentativeFeatureSupported && isInternalCompany;

        }

        private List<LocationInformation> GetAllLocations()
        {
            LocationFacade facade = new LocationFacade();
            return facade.GetAllLocations();
        }

        private List<CompanyInformation> GetAllCompanies()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            CompanyFacade facade = new CompanyFacade();
            return cruxSecurityManager.GetAllExternalCompanies();
        }


        private void CheckValidity()
        {
            SessionData sessionData = new SessionData();
            UserInformation currentUser = (UserInformation)sessionData.CurrentUser;
            UserInformation userBeingModified = _view.ConcernedUserDetails.ConcernedUser;
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            if (!cruxSecurityManager.IsUserAuthorizedToEditUser(currentUser, userBeingModified))
                NavigationController.OpenErrorPage("801");
        }

        private List<RoleInformation> GetRoles(int companyid)
        {
            SessionData sessionData = new SessionData();
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            RoleFacade roleFacade = new RoleFacade();
            List<RoleInformation> roles = new List<RoleInformation>();
            if (cruxSecurityManager.IsUserSuperAdministrator(sessionData.CurrentUser))
                roles = cruxSecurityManager.GetAllRolesByCompanyID(companyid);
            else if (cruxSecurityManager.IsUserGlobalAdministrator(sessionData.CurrentUser))
                roles = cruxSecurityManager.GetNonSuperAdminisativeRoles(companyid);
            else
                roles = cruxSecurityManager.GetNonGlobalAdminisativeRoles(companyid);
            return roles;
        }

        private List<DepartmentInformation> GetAllDepartments(int companyid)
        {
            DepartmentFacade deparmentFacade = new DepartmentFacade();
            return deparmentFacade.GetDepartments(companyid);
        }
        public void ModifyDetails()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            bool sucess = false;
            int companyId = 0;
            try
            {
                companyId = int.Parse((new SessionData()).PageData.ToString());
                cruxSecurityManager.ModifyUserDetails(_view.ConcernedUserDetails, companyId);
                sucess = true;
                IProcessor<UserInformation> plugObject = (IProcessor<UserInformation>)CruxConfigurationManager.GetProcessor("UserRoleProcessor");
                if (plugObject != null)
                {
                    plugObject.FirePostprocessAction(_view.ConcernedUserDetails.ConcernedUser);
                }
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
            }
            if (sucess) OpenRelevantView();
        }

        private void OpenRelevantView()
        {
            SessionData sessionData = new SessionData();
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserInformation currentUser = sessionData.CurrentUser;
            int currentUserCompanyID = int.Parse((new SessionData()).PageData.ToString());
            if (cruxSecurityManager.IsUserSuperAdminOrCompanyAdmin(currentUser, currentUserCompanyID))
                NavigateToManageUsersScreen();
            else
                NavigationController.OpenView("Administration");
        }


        public UserInformation GetUserInformation(int concernedUserId)
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserFacade userFacade = new UserFacade();
            UserInformation userInformation = cruxSecurityManager.GetUser(concernedUserId);
            return userInformation;
        }

        public void NavigateToManageUsersScreen()
        {
            int companyId = int.Parse((new SessionData()).PageData.ToString());
            NavigationController.OpenView("ManageUsers", companyId);
        }
    }
}
